c************************************************************
c*
c***********************************************************
      SUBROUTINE MAINBOX1(N,X,D,D1,Z,Z1,XOLD,NUM_ITER,
     *DOLDALFA,IPRINT,DCONV,FSTOP,XFSTOP,FINIT,FFSTOP)

      IMPLICIT NONE
      INTEGER N,I,J,I_CORR,NUM_FUNCT,NUM_ITER
      INTEGER NUM_FAL,NUM_SUCC,ISTOP
      INTEGER IPRINT
	INTEGER IMIN,IMAX,IMINALFA,IMAXALFA

      REAL*8 DCONV(N),DNR,FFM
      REAL*8 X(N),Z(N),Z1(N),D(N),D1(N),XOLD(N)
      REAL*8 DOLDALFA(N),GAMMA,RHO,ALFA
      REAL*8 F,FZ 
      REAL*8 DOLDALFAMEDIO,DALFAMAX
      REAL*8 FMIN,FMAX,ALFA0,DOLDALFAMIN,DOLDALFAMAX
      REAL*8 RAPALFA,FINIT(N,2)

C     VETTORE DEI VALORI DI F SUI PUNTI DI UN SIMPLESSO N+1 DIM.

      REAL*8 FSTOP(N+1),XFSTOP(N,N+1),FFSTOP,FMM

c     num_fal rappresenta il numero di fallimenti consecutivi

c     i_corr rappresenta l'indice della direzione corrente

      COMMON /NUM/F
      COMMON /NUMNEW/NUM_FUNCT

c     inizializzazione

      NUM_SUCC=0

      GAMMA=1.D-6
      RHO=1.D-1

      NUM_FUNCT = 0
      NUM_ITER = 0 
      NUM_FAL=0
      ISTOP = 0

      I_CORR=1

      ALFA0=1.D0

      DO I=1,N

C      
        IF(IPRINT.GE.2) THEN
          WRITE(*,*) ' ALFAiniz(',I,')=',DOLDALFA(I)
          WRITE(1,*) ' ALFAiniz(',I,')=',DOLDALFA(I)
        ENDIF
C
      END DO

c     scelta iniziale delle direzioni

      
      CALL FUNCT(X,N,F)
!	WRITE(*,*)'MAINBOX1: ',X,F
!	WRITE(1,*)'MAINBOX1: ',X,F
	NUM_FUNCT=NUM_FUNCT+1

      FSTOP(1)=F

      DO I=1,N
        XFSTOP(I,1)=X(I)
	  Z(I)=X(I)
      END DO

      IF(IPRINT.GE.2) THEN
        WRITE(*,*) ' ----------------------------------'
        WRITE(1,*) ' ----------------------------------'
        WRITE(*,*) ' Finiz =',F
        WRITE(1,*) ' Finiz =',F
        DO I=1,N
          WRITE(*,*) ' Xiniz(',I,')=',X(I)
          WRITE(1,*) ' Xiniz(',I,')=',X(I)
        ENDDO
      ENDIF
 
      NUM_FAL=0


C---------------------------
C     CICLO PRINCIPALE
C---------------------------

  1   CONTINUE

      IF(I_CORR.EQ.1) THEN
           DO I=1,N
                DCONV(I)=-D(I)
           END DO
      ENDIF

	ISTOP = 0

      DALFAMAX=MAXVAL(DOLDALFA)

      IF(IPRINT.GE.1) THEN
        WRITE(*,*) '----------------------------------------------'
        WRITE(1,*) '----------------------------------------------'
        WRITE(*,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
        WRITE(1,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
      ENDIF

      IF (ISTOP.EQ.1) THEN
!        WRITE(2,50)'&',N,'&',NUM_FUNCT,'&',F,'\\'  
   50   FORMAT(1X,a3,i5,a3,i5,a3,d13.5,a6)
!        WRITE(*,*) '----------------------------------------------'
!        WRITE(1,*) '----------------------------------------------'
!        WRITE(*,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
!        WRITE(1,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
        RETURN
      END IF

C-------------------------------------
C    CAMPIONAMENTO LUNGO ASSE I_CORR
C-------------------------------------
 
      CALL LINESEARCH_INVERTI(N,X,F,D,ALFA,DOLDALFA,Z,FZ,GAMMA,RHO,
     *I_CORR,NUM_FAL,NUM_ITER,DALFAMAX,IPRINT)

!      CALL LINESEARCH(N,X,F,D,ALFA,DOLDALFA,Z,FZ,GAMMA,RHO,
!     *I_CORR,NUM_FAL,NUM_ITER,DALFAMAX,IPRINT)        

      IF(DABS(ALFA).GE.1.D-24) THEN

          X(I_CORR) = X(I_CORR)+ALFA*D(I_CORR)
          Z(I_CORR) = X(I_CORR)

          F=FZ
          DO I=N+1,2,-1
             FSTOP(I)=FSTOP(I-1)
             DO J=1,N
                XFSTOP(J,I)=XFSTOP(J,I-1)
             END DO
          ENDDO
          FSTOP(1)=F
          DO J=1,N
             XFSTOP(J,1)=X(J)
          END DO            
          NUM_FAL=0
          NUM_ITER=NUM_ITER+1
          NUM_SUCC=NUM_SUCC+1
    
          IF(IPRINT.GE.1) THEN
             WRITE(*,*) ' F =',F
             WRITE(1,*) ' F =',F
          ENDIF

          IF(IPRINT.GE.2) THEN
	       DO I=1,N
                WRITE(*,*) ' X(',I,')=',X(I)
                WRITE(1,*) ' X(',I,')=',X(I)
             ENDDO
          ENDIF
      
	ELSE
      
	    DO I=N+1,2,-1
             FSTOP(I)=FSTOP(I-1)
             DO J=1,N
                XFSTOP(J,I)=XFSTOP(J,I-1)
             END DO
          ENDDO
          FSTOP(1)=FZ
          DO J=1,N
             XFSTOP(J,1)=Z(J)  
          END DO       
          NUM_FAL=NUM_FAL+1
          NUM_ITER=NUM_ITER+1
          Z(I_CORR) = X(I_CORR)
		      
	END IF

      IF(I_CORR.LT.N) THEN

          I_CORR=I_CORR+1

      ELSE

	go to 10

!          CALL STOP(N,DOLDALFA,ISTOP,DALFAMAX,NUM_FUNCT,FSTOP,ALFA_STOP,
!     *               FFSTOPTOL,FFSTOP,FOTT)

	    IF (ISTOP.EQ.1) THEN
!             WRITE(2,50)'&',N,'&',NUM_FUNCT,'&',F,'\\'  
!             WRITE(*,*) '----------------------------------------------'
!             WRITE(1,*) '----------------------------------------------'
!             WRITE(*,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
!             WRITE(1,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
             RETURN
          END IF

C     ------------------------------------------
C        calcolo direzione n+1
C     ------------------------------------------

          FMIN=FSTOP(1)
          FMAX=FSTOP(1)
          IMIN=1
          IMAX=1
          DOLDALFAMIN=DOLDALFA(1)
          DOLDALFAMAX=DOLDALFA(1)
          IMINALFA=1
          IMAXALFA=1
          do i=2,n
             if(doldalfa(i).lt.doldalfamin) then
                doldalfamin=doldalfa(i)
                iminalfa=i
             end if 
             if(doldalfa(i).gt.doldalfamax) then
                doldalfamax=doldalfa(i)
                imaxalfa=i
             end if 
          end do
   
          rapalfa=1.d+6
c	     rapalfa=-1.d+36
c          rapalfa=10.d0

          if(doldalfamax/doldalfamin.gt.rapalfa) then
             do i=1,n
                 D1(i)=dconv(i)
             end do
             dnr=dsqrt(DFLOAT(N))
	    else
             do i=2,n+1
                if(fstop(i).lt.fmin) then
                   fmin=fstop(i)
                   imin=i
                end if
                if(fstop(i).gt.fmax) then
                   fmax=fstop(i)
                   imax=i
                end if
             end do

             DNR=0.D0
             DOLDALFAMEDIO=(DOLDALFAMAX+DOLDALFAMIN)/2.D0
             DO I=1,N
                D1(I)=(XFSTOP(I,IMIN)-XFSTOP(I,IMAX))/DOLDALFAMAX
C                D1(I)=(XFSTOP(I,IMIN)-XFSTOP(I,IMAX))/DOLDALFAMIN
C                D1(I)=(XFSTOP(I,IMIN)-XFSTOP(I,IMAX))/DOLDALFAMEDIO
C                D1(I)=X(I)-XFSTOP(I,IMAX)
                DNR=DNR+D1(I)*D1(I)
             END DO
             DNR=DSQRT(DNR)

             IF(DNR.LE.1.D-24) THEN
	           do i=1,n
                   D1(i)=dconv(i)
                 end do
                 dnr=dsqrt(DFLOAT(N))
             ENDIF
          
C            DO I=1,N
C              D(I)=D(I)/DNR
C            END DO
C            DNR=1.D0 

C            SUM=0.D0
C            DO I=1,N+1
CC             WEIGHT(I)=DMAX1(0.D0,FSTOP(I)-F)
C               WEIGHT(I)=DABS(FSTOP(I)-F)
C               SUM=SUM+WEIGHT(I)
C             ENDDO
 
C             DO I=1,N+1
C                WEIGHT(I)=WEIGHT(I)/SUM
C             ENDDO

C             DNR=0.D0
C             DO I=1,N
C                D1(I)=0.D0
C                DO J=1,N+1
CC                 D1(I)=D1(I)+WEIGHT(J)*(X(I)-XFSTOP(I,J))
C                 D1(I)=D1(I)+((FSTOP(J)-F)/SUM)*(X(I)-XFSTOP(I,J))
C                ENDDO
C                DNR=DNR+D1(I)*D1(I)
C             END DO
C             DNR=DSQRT(DNR)
C     --------------------------------------------

          endif

C-------------------------------------
C    CAMPIONAMENTO LUNGO DIREZIONE n+1
C-------------------------------------

          CALL LINESEARCH1(n,x,f,z1,d1,dnr,alfa0,gamma,alfa,fz,
     *                   iprint,NUM_FUNCT)


          if(dabs(alfa).ge.1.d-24) then
             do i=1,n
                x(i) = x(i)+alfa*d1(i)
	          Z(I)=X(I)
             end do
             f=fz
 
             num_fal=0

             DO I=N+1,2,-1
               FSTOP(I)=FSTOP(I-1)
               DO J=1,N
                 XFSTOP(J,I)=XFSTOP(J,I-1)
                END DO
           ENDDO

             fstop(1)=f
              
             do j=1,n
               xfstop(j,1)=x(j)
             end do

             num_iter=num_iter+1
    
             if(iprint.ge.1) then
                write(*,*) ' f =',f
                write(1,*) ' f =',f
             endif

             if(iprint.ge.2) then
                do i=1,n
                   write(*,*) ' x(',i,')=',x(i)
                   write(1,*) ' x(',i,')=',x(i)
                enddo
             endif

          else
	       do i=1,n
c	          Z(I)=X(I)
             end do

             alfa0=0.5d0*alfa0

          end if

   10     continue

          I_CORR=1
		ISTOP = 1

	    IF (ISTOP.EQ.1) THEN
!             WRITE(2,50)'&',N,'&',NUM_FUNCT,'&',F,'\\'  
!             WRITE(*,*) '----------------------------------------------'
!             WRITE(1,*) '----------------------------------------------'
!             WRITE(*,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
!             WRITE(1,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
              FFM=0.D0
		    DO I=1,N+1
			  FFM=FFM+FSTOP(I)
			ENDDO
			FFM=FFM/DFLOAT((N+1))

			FFSTOP=0.D0
			DO I=1,N+1
			  FFSTOP=FFSTOP+(FSTOP(I)-FFM)*(FSTOP(I)-FFM)
			ENDDO
		!	write(*,*) ' ffstop =',ffstop,  ' dfloat =',dfloat(n+1),' ffm =',ffm
			FFSTOP=DSQRT(FFSTOP/DFLOAT(N+1))

             RETURN
          END IF

      END IF 

      GO TO 1

      END
        
c************************************************************
c*
c***********************************************************
      SUBROUTINE MAINBOX2(N,X,D,D1,Z,Z1,XOLD,NUM_ITER,DOLDALFA,
     *ALFA_STOP,IPRINT,DCONV,FSTOP,XFSTOP,FINIT,FFSTOP,
     *FFSTOPTOL,FOTT,ALFAOTT,XOTT,WKS,IDIMWKS,ISTOP,MASCH,MAXNF,fglob)
	
      IMPLICIT NONE
	INCLUDE 'TYPEDECL.FI'

      INTEGER N,I,J,I_CORR,NUM_FUNCT,NUM_ITER,IDIMWKS,MAXNF
      INTEGER NUM_FAL,NUM_SUCC,ISTOP
      INTEGER IPRINT
	INTEGER IMIN,IMAX,IMINALFA,IMAXALFA

      REAL*8 DCONV(N),DNR,ALFA_STOP,fglob
      REAL*8 X(N),Z(N),Z1(N),D(N),D1(N),XOLD(N),XOTT(N)
      REAL*8 DOLDALFA(N),GAMMA,RHO,ALFA,FOTT,ALFAOTT
      REAL*8 F,FZ 
      REAL*8 DOLDALFAMEDIO,DALFAMAX
      REAL*8 FMIN,FMAX,ALFA0,DOLDALFAMIN,DOLDALFAMAX
      REAL*8 RAPALFA,FINIT(N,2)
	TYPE(COMP_WKS_TYP)	:: WKS(IDIMWKS)

C     VETTORE DEI VALORI DI F SUI PUNTI DI UN SIMPLESSO N+1 DIM.

      REAL*8 FSTOP(N+1),XFSTOP(N,N+1),FFSTOP,FFSTOPTOL
	LOGICAL MASCH(IDIMWKS)

c     num_fal rappresenta il numero di fallimenti consecutivi

c     i_corr rappresenta l'indice della direzione corrente

      COMMON /NUM/F
      COMMON /NUMNEW/NUM_FUNCT

c     inizializzazione

      NUM_SUCC=0

      GAMMA=1.D-6
      RHO=1.D-1

      NUM_FUNCT = 0
      NUM_ITER = 0 
      NUM_FAL=0
      ISTOP = 0

      I_CORR=1

      ALFA0=1.D0

c      DO I=1,N

c        DOLDALFA(I)=1.D0

c        DOLDALFA(I)=DMAX1(5.D-1,DMIN1(2.D+0,5.D-1*DABS(X(I))))
c        DOLDALFA(I)=1.0D0*DMAX1(1.D-3,DMIN1(1.D+3,0.5D0*DABS(X(I))))
      
c        IF(IPRINT.GE.2) THEN
c          WRITE(*,*) ' ALFAiniz(',I,')=',DOLDALFA(I)
c          WRITE(1,*) ' ALFAiniz(',I,')=',DOLDALFA(I)
c        ENDIF

C      END DO

c     scelta iniziale delle direzioni

	DALFAMAX = MAXVAL(DOLDALFA)

      DO I=1,N      
        D(I)=1.D0 
      END DO
       
      CALL FUNCT(X,N,F)
	NUM_FUNCT=NUM_FUNCT+1

      FSTOP(1)=F

      DO I=1,N
        XFSTOP(I,1)=X(I)
	  Z(I)=X(I)
      END DO

      IF(IPRINT.GE.2) THEN
        WRITE(*,*) ' ----------------------------------'
        WRITE(1,*) ' ----------------------------------'
        WRITE(*,*) ' Finiz =',F
        WRITE(1,*) ' Finiz =',F
        DO I=1,N
          WRITE(*,*) ' Xiniz(',I,')=',X(I)
          WRITE(1,*) ' Xiniz(',I,')=',X(I)
        ENDDO
      ENDIF
 
      NUM_FAL=0

c      CALL INIT_STEPS(N,DOLDALFA,X,F,NUM_FUNCT,D,Z,FINIT)

C---------------------------
C     CICLO PRINCIPALE
C---------------------------

  1   CONTINUE

      IF(I_CORR.EQ.1) THEN
           DO I=1,N
                DCONV(I)=-D(I)
           END DO
      ENDIF

      IF(NUM_ITER.GE.N) THEN
        CALL STOP(N,DOLDALFA,ISTOP,DALFAMAX,NUM_FUNCT,FSTOP,
     *			    ALFA_STOP,FFSTOPTOL,FFSTOP,FOTT,X,XOTT,ALFAOTT,
     *				WKS,IDIMWKS,MASCH,MAXNF,fglob)
      ENDIF

      IF(IPRINT.GE.1) THEN
        WRITE(*,*) '----------------------------------------------'
        WRITE(1,*) '----------------------------------------------'
        WRITE(*,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
        WRITE(1,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
      ENDIF

      IF (ISTOP.GE.1) THEN
!        WRITE(2,50)'&',N,'&',NUM_FUNCT,'&',F,'\\'  
   50   FORMAT(1X,a3,i5,a3,i5,a3,d13.5,a6)
!        WRITE(*,*) '----------------------------------------------'
!        WRITE(1,*) '----------------------------------------------'
!        WRITE(*,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
!        WRITE(1,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
        RETURN
      END IF

C-------------------------------------
C    CAMPIONAMENTO LUNGO ASSE I_CORR
C-------------------------------------
 

      CALL LINESEARCH_INVERTI(N,X,F,D,ALFA,DOLDALFA,Z,FZ,GAMMA,RHO,
     *I_CORR,NUM_FAL,NUM_ITER,DALFAMAX,IPRINT)
C      CALL LINESEARCH_INVERTI(N,X,F,D,ALFA,DOLDALFA,Z,FZ,GAMMA,RHO,
C     *I_CORR,NUM_FAL,NUM_ITER,ALFA_STOP,IPRINT)

        
!      CALL LINESEARCH(N,X,F,D,ALFA,DOLDALFA,Z,FZ,GAMMA,RHO,
!     *I_CORR,NUM_FAL,NUM_ITER,DALFAMAX,IPRINT)

      IF(DABS(ALFA).GE.1.D-24) THEN

          X(I_CORR) = X(I_CORR)+ALFA*D(I_CORR)
          Z(I_CORR) = X(I_CORR)

          F=FZ
          DO I=N+1,2,-1
             FSTOP(I)=FSTOP(I-1)
             DO J=1,N
                XFSTOP(J,I)=XFSTOP(J,I-1)
             END DO
          ENDDO
          FSTOP(1)=F
          DO J=1,N
             XFSTOP(J,1)=X(J)
          END DO            
          NUM_FAL=0
          NUM_ITER=NUM_ITER+1
          NUM_SUCC=NUM_SUCC+1
    
          IF(IPRINT.GE.1) THEN
             WRITE(*,*) ' F =',F
             WRITE(1,*) ' F =',F
          ENDIF

          IF(IPRINT.GE.2) THEN
	       DO I=1,N
                WRITE(*,*) ' X(',I,')=',X(I)
                WRITE(1,*) ' X(',I,')=',X(I)
             ENDDO
          ENDIF
      
	ELSE
      
	    DO I=N+1,2,-1
             FSTOP(I)=FSTOP(I-1)
             DO J=1,N
                XFSTOP(J,I)=XFSTOP(J,I-1)
             END DO
          ENDDO
          FSTOP(1)=FZ
          DO J=1,N
             XFSTOP(J,1)=Z(J)  
          END DO       
          NUM_FAL=NUM_FAL+1
          NUM_ITER=NUM_ITER+1
          Z(I_CORR) = X(I_CORR)
		      
	END IF

      IF(I_CORR.LT.N) THEN

          I_CORR=I_CORR+1

      ELSE

          go to 10

          CALL STOP(N,DOLDALFA,ISTOP,DALFAMAX,NUM_FUNCT,FSTOP,ALFA_STOP,
     *	 FFSTOPTOL,FFSTOP,FOTT,X,XOTT,ALFAOTT,WKS,IDIMWKS,MASCH,MAXNF,
     *	 fglob)

	    IF (ISTOP.GE.1) THEN
!             WRITE(2,50)'&',N,'&',NUM_FUNCT,'&',F,'\\'  
!             WRITE(*,*) '----------------------------------------------'
!             WRITE(1,*) '----------------------------------------------'
!             WRITE(*,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
!             WRITE(1,*) 'NF=',NUM_FUNCT,'   F=',F,'   ALFAmax=',DALFAMAX
             RETURN
          END IF

C     ------------------------------------------
C        calcolo direzione n+1
C     ------------------------------------------

          FMIN=FSTOP(1)
          FMAX=FSTOP(1)
          IMIN=1
          IMAX=1
          DOLDALFAMIN=DOLDALFA(1)
          DOLDALFAMAX=DOLDALFA(1)
          IMINALFA=1
          IMAXALFA=1
          do i=2,n
             if(doldalfa(i).lt.doldalfamin) then
                doldalfamin=doldalfa(i)
                iminalfa=i
             end if 
             if(doldalfa(i).gt.doldalfamax) then
                doldalfamax=doldalfa(i)
                imaxalfa=i
             end if 
          end do
   
          rapalfa=1.d+6
c	     rapalfa=-1.d+36
c          rapalfa=10.d0

          if(doldalfamax/doldalfamin.gt.rapalfa) then
             do i=1,n
                 D1(i)=dconv(i)
             end do
             dnr=dsqrt(DFLOAT(N))
	    else
             do i=2,n+1
                if(fstop(i).lt.fmin) then
                   fmin=fstop(i)
                   imin=i
                end if
                if(fstop(i).gt.fmax) then
                   fmax=fstop(i)
                   imax=i
                end if
             end do

             DNR=0.D0
             DOLDALFAMEDIO=(DOLDALFAMAX+DOLDALFAMIN)/2.D0
             DO I=1,N
                D1(I)=(XFSTOP(I,IMIN)-XFSTOP(I,IMAX))/DOLDALFAMAX
C                D1(I)=(XFSTOP(I,IMIN)-XFSTOP(I,IMAX))/DOLDALFAMIN
C                D1(I)=(XFSTOP(I,IMIN)-XFSTOP(I,IMAX))/DOLDALFAMEDIO
C                D1(I)=X(I)-XFSTOP(I,IMAX)
                DNR=DNR+D1(I)*D1(I)
             END DO
             DNR=DSQRT(DNR)

             IF(DNR.LE.1.D-24) THEN
	           do i=1,n
                   D1(i)=dconv(i)
                 end do
                 dnr=dsqrt(DFLOAT(N))
             ENDIF
          
C            DO I=1,N
C              D(I)=D(I)/DNR
C            END DO
C            DNR=1.D0 

C            SUM=0.D0
C            DO I=1,N+1
CC             WEIGHT(I)=DMAX1(0.D0,FSTOP(I)-F)
C               WEIGHT(I)=DABS(FSTOP(I)-F)
C               SUM=SUM+WEIGHT(I)
C             ENDDO
 
C             DO I=1,N+1
C                WEIGHT(I)=WEIGHT(I)/SUM
C             ENDDO

C             DNR=0.D0
C             DO I=1,N
C                D1(I)=0.D0
C                DO J=1,N+1
CC                 D1(I)=D1(I)+WEIGHT(J)*(X(I)-XFSTOP(I,J))
C                 D1(I)=D1(I)+((FSTOP(J)-F)/SUM)*(X(I)-XFSTOP(I,J))
C                ENDDO
C                DNR=DNR+D1(I)*D1(I)
C             END DO
C             DNR=DSQRT(DNR)
C     --------------------------------------------

          endif

C-------------------------------------
C    CAMPIONAMENTO LUNGO DIREZIONE n+1
C-------------------------------------

          CALL LINESEARCH1(n,x,f,z1,d1,dnr,alfa0,gamma,alfa,fz,
     *                   iprint,NUM_FUNCT)


          if(dabs(alfa).ge.1.d-24) then
             do i=1,n
                x(i) = x(i)+alfa*d1(i)
	          Z(I)=X(I)
             end do
             f=fz
 
             num_fal=0

             DO I=N+1,2,-1
               FSTOP(I)=FSTOP(I-1)
               DO J=1,N
                 XFSTOP(J,I)=XFSTOP(J,I-1)
                END DO
           ENDDO

             fstop(1)=f
              
             do j=1,n
               xfstop(j,1)=x(j)
             end do

             num_iter=num_iter+1
    
             if(iprint.ge.1) then
                write(*,*) ' f =',f
                write(1,*) ' f =',f
             endif

             if(iprint.ge.2) then
                do i=1,n
                   write(*,*) ' x(',i,')=',x(i)
                   write(1,*) ' x(',i,')=',x(i)
                enddo
             endif

          else
	       do i=1,n
c	          Z(I)=X(I)
             end do

             alfa0=0.5d0*alfa0

          end if

   10     continue

          I_CORR=1

      END IF 

      GO TO 1

      END


C     #######################################################

      SUBROUTINE STOP(N,DOLDALFA,ISTOP,DALFAMAX,NUM_FUNCT,FSTOP,
     *			    ALFA_STOP,FFSTOPTOL,FFSTOP,FOTT,X,
     *		      XOTT,ALFAOTT,WKS,IDIMWKS,MASCH,MAXNF,fglob)
C	USE IMSLF90

      IMPLICIT NONE

	INCLUDE 'TYPEDECL.FI'
      
      INTEGER N,ISTOP,I,NUM_FUNCT,IDIMWKS,J,IMAX,MAXNF
      REAL*8 DOLDALFA(N),DALFAMAX,FSTOP(N+1),FFSTOP,FFM,ALFA_STOP,F
     *	,XOTT(N),X(N)
	REAL*8 FFSTOPTOL,FOTT,ALFAOTT,fglob
	TYPE(COMP_WKS_TYP)	:: WKS(IDIMWKS)

	LOGICAL NORMADUE,L_F_DISTANTI,NON_MINIMIZZ,L_F_VICINI
        LOGICAL MASCH(IDIMWKS)

	COMMON/CALFANR2/NORMADUE
      COMMON/NUM/F

      ISTOP=0
	NON_MINIMIZZ = .FALSE.

!	WRITE(*,*)'STO DENTRO STOP ! ALFA_STOP = ',ALFA_STOP
!	WRITE(1,*)'STO DENTRO STOP ! ALFA_STOP = ',ALFA_STOP
CC	PAUSE
      DALFAMAX=DOLDALFA(1)
      DO I=1,N
        IF(DOLDALFA(I).GT.DALFAMAX) THEN
          DALFAMAX=DOLDALFA(I)
        END IF
      END DO
     
C      FFM=1.D+30
C      DO I=1,N+1
C        IF(FSTOP(I).LT.FFM) FFM=FSTOP(I)
C      ENDDO

      FFM=0.D0
      DO I=1,N+1
        FFM=FFM+FSTOP(I)
      ENDDO
      FFM=FFM/DFLOAT((N+1))

      FFSTOP=0.D0
      DO I=1,N+1
        FFSTOP=FFSTOP+(FSTOP(I)-FFM)*(FSTOP(I)-FFM)
      ENDDO
!	write(*,*) ' ffstop =',ffstop,  ' dfloat =',dfloat(n+1),' ffm =',ffm
      FFSTOP=DSQRT(FFSTOP/DFLOAT(N+1))

	IF(NORMADUE) THEN
		IF(DSQRT(DOT_PRODUCT(DOLDALFA,DOLDALFA)).LE.ALFA_STOP) THEN
		  ISTOP = 1
		END IF
	ELSE
		IF(DALFAMAX.LE.ALFA_STOP) THEN
		  ISTOP = 1
		END IF
	ENDIF

!--------------------------------------
!		calcola l'indice imax della
!		componente di wks contenente
!		il valore di fob piu' alto
!--------------------------------------
		IMAX = 1
		DO I = 2,IDIMWKS
			IF((WKS(I)%FOB > WKS(IMAX)%FOB).AND.(.NOT.MASCH(I))) THEN
				IMAX = I
			ENDIF
		ENDDO

	L_F_DISTANTI = ((F-WKS(IMAX)%FOB)/DMAX1(1.D-8,
     *					DMIN1(DABS(F),DABS(WKS(IMAX)%FOB))) ).GE.1.D-6
	L_F_DISTANTI = L_F_DISTANTI.AND.
     *			   (DALFAMAX.LE.1.D+0*WKS(IMAX)%ALFAMAX)

	IF (L_F_DISTANTI) THEN
		ISTOP = 1
		RETURN
	ENDIF

	DO J = 1,IDIMWKS

		IF(F > FOTT) THEN

			L_F_VICINI = (DABS(F-WKS(J)%FOB)/(DMAX1(1.D-8,
     *			DABS(DMAX1(F,WKS(J)%FOB) ))) ).LE.1.D-1
			L_F_VICINI = L_F_VICINI.AND.((DSQRT(													
     *			DOT_PRODUCT(X-WKS(J)%X,X-WKS(J)%X)) <= 1.D-1)
     *			.OR.(DALFAMAX.LE.1.D+1*WKS(J)%ALFAMAX))
!			L_F_VICINI = L_F_VICINI.AND.(DSQRT(													
!     *			DOT_PRODUCT(X-WKS(J)%X,X-WKS(J)%X)) <= 1.D-1)

			IF (L_F_VICINI) THEN 
			
!				ISTOP=1
!				RETURN

			ENDIF
		ENDIF
	ENDDO

	L_F_DISTANTI = ((F-FOTT)/DMAX1(1.D-3,DMIN1(DABS(F),DABS(FOTT))
     *										  ) ).GE.1.D+1
	L_F_DISTANTI = L_F_DISTANTI.AND.
     *			   (DALFAMAX.LE.1.D+1*ALFA_STOP)

	L_F_VICINI = ((F-FOTT)/DMAX1(1.D-8,DABS(DMAX1(F,FOTT)) 
     *										  ) ).LE.1.D-1

C	L_F_VICINI = L_F_VICINI.AND.((DSQRT(DOT_PRODUCT(X-XOTT,X-XOTT))
C     *			<= 1.D-1))

	L_F_VICINI = L_F_VICINI.AND.((DSQRT(DOT_PRODUCT(X-XOTT,X-XOTT))
     *			<= 1.D-1) .OR. (DALFAMAX <= 0.5D+0*ALFAOTT))

c	L_F_DISTANTI = ((F-FOTT)/DMAX1(1.D-16,DMAX1( DABS(FOTT),
c     *										DABS(F) ) ) ).GE.5.D-1
c	NON_MINIMIZZ = L_F_DISTANTI.AND.
c     *			   (DALFAMAX.LE.DMIN1(1.0D-0,1.D+2*ALFA_STOP))

!	NON_MINIMIZZ = L_F_DISTANTI.AND.(DALFAMAX.LE.1.D-3)
	
	NON_MINIMIZZ = L_F_DISTANTI .OR. L_F_VICINI

	IF(NON_MINIMIZZ) ISTOP = 1

C      IF(FFSTOP.LE.FFSTOPTOL) THEN
C        ISTOP = 1
C      END IF
      IF(NUM_FUNCT.GT.MAXNF) THEN
        ISTOP = 1
      END IF
	
	if((f-fglob)/max(1.0d0,abs(fglob))<1.0d-4) then
		istop = 1
	endif
	if((fott-fglob)/max(1.0d0,abs(fglob))<1.0d-4) then
		istop = 1
	endif

      RETURN

      END




C     *********************************************************
C     *         
C     *         ALGORITMO PL
C     *
C     ********************************************************

      SUBROUTINE LINESEARCH(N,X,F,D,ALFA,DOLDALFA,Z,FZ,
     *GAMMA,RHO,I_CORR,NUM_FAL,NUM_ITER,
     *DALFAMAX,IPRINT)
     
      IMPLICIT NONE

      INTEGER N,I_CORR,NUM_FUNCT
      INTEGER I,J,L,LL
      INTEGER NUM_ITER,NUM_FAL
      INTEGER IPRINT
      REAL*8 X(N),D(N),DOLDALFA(N),Z(N),Z1(N)
      REAL*8 F,ALFA,FZ,GAMMA,RHO,DNR
      REAL*8 DELTA,DELTA1,FPAR,FZDELTA
      REAL*8 ALFAEX,FMIN,ALFAMIN 
      REAL*8 DALFAMAX,FCOMMON
      REAL*8 ALFAOLD,FZOLD
	LOGICAL PRIMA_VOLTA

      COMMON /NUM/FCOMMON
	COMMON /NUMNEW/NUM_FUNCT

	PRIMA_VOLTA = .TRUE.
      DELTA =0.5D0
      DELTA1 =0.5D0
      DNR=1.D0


c     indice della direzione corrente

      J=I_CORR

      IF(IPRINT.GE.1) THEN
         WRITE(*,*) ' J=',J,'  D(J)=',D(J),'  DOLDALFA=',DOLDALFA(J)
         WRITE(1,*) ' J=',J,'  D(J)=',D(J),'  DOLDALFA=',DOLDALFA(J)
      ENDIF

 10   CONTINUE

      ALFA=DOLDALFA(J)

      IF(DABS(ALFA).LE.1.D-3*DALFAMAX) THEN
C	IF(DABS(ALFA).LT.0.D0) THEN

          D(J)=-D(J)

C         IF(IPRINT.GE.1) THEN
C            WRITE(*,*) ' direzione opposta'
C            WRITE(1,*) ' direzione opposta'
C            WRITE(*,*) ' ALFA=',ALFA,'    ALFAMAX=',DALFAMAX
C            WRITE(1,*) ' ALFA=',ALFA,'    ALFAMAX=',DALFAMAX
C         ENDIF

	   
	   ALFA=0.D0
         RETURN
      
      END IF

20	CONTINUE

      Z(J) = X(J)+ALFA*D(J)

      ALFAEX=ALFA
       
      CALL FUNCT(Z,N,FZ)
      NUM_FUNCT=NUM_FUNCT+1

      IF(IPRINT.GE.1) THEN
         WRITE(*,*) ' FZ =',FZ,'   ALFA =',ALFA
         WRITE(1,*) ' FZ =',FZ,'   ALFA =',ALFA
      ENDIF
      IF(IPRINT.GE.2) THEN
         DO I=1,N
            WRITE(*,*) ' Z(',I,')=',Z(I)
            WRITE(1,*) ' Z(',I,')=',Z(I)
         ENDDO
      ENDIF

        
      FPAR= F-GAMMA*ALFA*ALFA*DNR*DNR

      IF(FZ.LE.FPAR) THEN
         FMIN=FZ
         ALFAMIN=ALFA 

C       controllo sull'espansione

   11    CONTINUE

         ALFAEX=ALFA/DELTA1

         Z(J) = X(J)+ALFAEX*D(J)
               
         CALL FUNCT(Z,N,FZDELTA)
         NUM_FUNCT=NUM_FUNCT+1

         IF(IPRINT.GE.1) THEN
            WRITE(*,*) ' FZex=',FZDELTA,'  ALFAEX=',ALFAEX  
            WRITE(1,*) ' FZex=',FZDELTA,'  ALFAEX=',ALFAEX
         ENDIF
         IF(IPRINT.GE.2) THEN
             DO I=1,N
                WRITE(*,*) ' Z(',I,')=',Z(I)
                WRITE(1,*) ' Z(',I,')=',Z(I)
             ENDDO
         ENDIF

         FPAR= F-GAMMA*ALFAEX*ALFAEX*DNR*DNR
         IF(FZDELTA.LE.FPAR) THEN
C           IF((FZDELTA.LE.FPAR).AND.(FZDELTA.LE.FZ)) THEN
C           IF(FZDELTA.LT.FMIN) THEN
                FZ=FZDELTA
                ALFA=ALFAEX
C                FMIN=FZDELTA
C                ALFAMIN=ALFAEX
                GO TO 11
C            ELSE
C                 FZ=FMIN
C                 ALFA=ALFAMIN
C                 DOLDALFA(J)=ALFAMIN
C                 RETURN
C            END IF
         ELSE
                  
c              DOLDALFA(J)=ALFA
              DOLDALFA(J)=DELTA*ALFA

              RETURN
         END IF

      ELSE 

          D(J)=-D(J)

          DOLDALFA(J)=DELTA*DOLDALFA(J)


          IF(IPRINT.GE.1) THEN
              WRITE(*,*) ' direzione opposta'
              WRITE(1,*) ' direzione opposta'
          ENDIF

C---------stima alfa iniz. in caso di doppio fallimento 2 ----
C          
C            IF((NUM_ITER.LT.N).AND.(IAPPR.EQ.1)) THEN
C            IF(IAPPR.EQ.1) THEN
C              WRITE(*,*) 'FZ=',FZ,'ALFA=',ALFA*D(J) 
C              DOLDALFA(J)=0.5D0*(FZOLD*ALFA*ALFA+F*
C     *       (ALFAOLD*ALFAOLD-ALFA*ALFA)-FZ*ALFAOLD*ALFAOLD)/
C     *       (FZOLD*ALFA+F*(ALFAOLD-ALFA)-FZ*ALFAOLD)
C              WRITE(*,*) ' DOLDALFA(J)=',DOLDALFA(J)
C              IF(DOLDALFA(J).GE.0.D0) THEN
C                DOLDALFA(J)=DMAX1(1.D-1,DOLDALFA(J))
C                D(J)=1.D0
C              ELSE
C                DOLDALFA(J)=DMAX1(1.D-1,-DOLDALFA(J))
C                D(J)=-1.D0
C              ENDIF
C            ENDIF
C-------------------------------------------------------------
C 
          ALFA=0.D0
          RETURN

      END IF

      END

      SUBROUTINE LINESEARCH_INVERTI(N,X,F,D,ALFA,DOLDALFA,Z,FZ,
     *GAMMA,RHO,I_CORR,NUM_FAL,NUM_ITER,
     *DALFAMAX,IPRINT)
     
      IMPLICIT NONE

      INTEGER N,I_CORR,NUM_FUNCT
      INTEGER I,J,L,LL
      INTEGER NUM_ITER,NUM_FAL
      INTEGER IPRINT
      REAL*8 X(N),D(N),DOLDALFA(N),Z(N),Z1(N)
      REAL*8 F,ALFA,FZ,GAMMA,RHO,DNR
      REAL*8 DELTA,DELTA1,FPAR,FZDELTA
      REAL*8 ALFAEX,FMIN,ALFAMIN 
      REAL*8 DALFAMAX,FCOMMON
      REAL*8 ALFAOLD,FZOLD
	LOGICAL PRIMA_VOLTA

      COMMON /NUM/FCOMMON
	COMMON /NUMNEW/NUM_FUNCT

	PRIMA_VOLTA = .TRUE.
      DELTA =0.5D0
      DELTA1 =0.5D0
      DNR=1.D0


c     indice della direzione corrente

      J=I_CORR

      IF(IPRINT.GE.1) THEN
         WRITE(*,*) ' J=',J,'  D(J)=',D(J),'  DOLDALFA=',DOLDALFA(J)
         WRITE(1,*) ' J=',J,'  D(J)=',D(J),'  DOLDALFA=',DOLDALFA(J)
      ENDIF

 10   CONTINUE

      ALFA=DOLDALFA(J)

      IF(DABS(ALFA).LE.1.D-3*DALFAMAX) THEN
C 	IF(DABS(ALFA).LT.0.D0) THEN

c          D(J)=-D(J)

C         IF(IPRINT.GE.1) THEN
C            WRITE(*,*) ' direzione opposta'
C            WRITE(1,*) ' direzione opposta'
C            WRITE(*,*) ' ALFA=',ALFA,'    ALFAMAX=',DALFAMAX
C            WRITE(1,*) ' ALFA=',ALFA,'    ALFAMAX=',DALFAMAX
c         ENDIF

	   
	   ALFA=0.D0
         RETURN
      
      END IF

20	CONTINUE

      Z(J) = X(J)+ALFA*D(J)

      ALFAEX=ALFA
       
      CALL FUNCT(Z,N,FZ)
      NUM_FUNCT=NUM_FUNCT+1

      IF(IPRINT.GE.1) THEN
         WRITE(*,*) ' FZ =',FZ,'   ALFA =',ALFA
         WRITE(1,*) ' FZ =',FZ,'   ALFA =',ALFA
      ENDIF
      IF(IPRINT.GE.2) THEN
         DO I=1,N
            WRITE(*,*) ' Z(',I,')=',Z(I)
            WRITE(1,*) ' Z(',I,')=',Z(I)
         ENDDO
      ENDIF

        
      FPAR= F-GAMMA*ALFA*ALFA*DNR*DNR

      IF(FZ.LE.FPAR) THEN
         FMIN=FZ
         ALFAMIN=ALFA 

C       controllo sull'espansione

   11    CONTINUE

         ALFAEX=ALFA/DELTA1

         Z(J) = X(J)+ALFAEX*D(J)
               
         CALL FUNCT(Z,N,FZDELTA)
         NUM_FUNCT=NUM_FUNCT+1

         IF(IPRINT.GE.1) THEN
            WRITE(*,*) ' FZex=',FZDELTA,'  ALFAEX=',ALFAEX  
            WRITE(1,*) ' FZex=',FZDELTA,'  ALFAEX=',ALFAEX
         ENDIF
         IF(IPRINT.GE.2) THEN
             DO I=1,N
                WRITE(*,*) ' Z(',I,')=',Z(I)
                WRITE(1,*) ' Z(',I,')=',Z(I)
             ENDDO
         ENDIF

         FPAR= F-GAMMA*ALFAEX*ALFAEX*DNR*DNR
         IF(FZDELTA.LE.FPAR) THEN
C           IF((FZDELTA.LE.FPAR).AND.(FZDELTA.LE.FZ)) THEN
C           IF(FZDELTA.LT.FMIN) THEN
                FZ=FZDELTA
                ALFA=ALFAEX
C                FMIN=FZDELTA
C                ALFAMIN=ALFAEX
                GO TO 11
C            ELSE
C                 FZ=FMIN
C                 ALFA=ALFAMIN
C                 DOLDALFA(J)=ALFAMIN
C                 RETURN
C            END IF
         ELSE
                  
c              DOLDALFA(J)=ALFA
              DOLDALFA(J)=DELTA*ALFA

              RETURN
         END IF

      ELSE 

          D(J)=-D(J)
		IF(PRIMA_VOLTA) THEN
			PRIMA_VOLTA = .FALSE.
			GO TO 20
		ENDIF

          DOLDALFA(J)=DELTA*DOLDALFA(J)


          IF(IPRINT.GE.1) THEN
              WRITE(*,*) ' direzione opposta'
              WRITE(1,*) ' direzione opposta'
          ENDIF

C---------stima alfa iniz. in caso di doppio fallimento 2 ----
C          
C            IF((NUM_ITER.LT.N).AND.(IAPPR.EQ.1)) THEN
C            IF(IAPPR.EQ.1) THEN
C              WRITE(*,*) 'FZ=',FZ,'ALFA=',ALFA*D(J) 
C              DOLDALFA(J)=0.5D0*(FZOLD*ALFA*ALFA+F*
C     *       (ALFAOLD*ALFAOLD-ALFA*ALFA)-FZ*ALFAOLD*ALFAOLD)/
C     *       (FZOLD*ALFA+F*(ALFAOLD-ALFA)-FZ*ALFAOLD)
C              WRITE(*,*) ' DOLDALFA(J)=',DOLDALFA(J)
C              IF(DOLDALFA(J).GE.0.D0) THEN
C                DOLDALFA(J)=DMAX1(1.D-1,DOLDALFA(J))
C                D(J)=1.D0
C              ELSE
C                DOLDALFA(J)=DMAX1(1.D-1,-DOLDALFA(J))
C                D(J)=-1.D0
C              ENDIF
C            ENDIF
C-------------------------------------------------------------
C 
          ALFA=0.D0
          RETURN

      END IF

      END



C*********************************************************
C
C********************************************************
      SUBROUTINE LINESEARCH1(N,X,F,Z,D,DNR,ALFA0,GAMMA,
     *                       ALFA,FZ,IPRINT,NUM_FUNCT)
      IMPLICIT NONE
      INTEGER N,IMIN,IMAX,I,J,NUM_FUNCT,IPRINT
      REAL*8 X(N),Z(N),F,ALFA0,FZ,GAMMA,DNR
      REAL*8 FPAR,ALFA,ALFAEX,DELTA,DELTA1,FZDELTA,D(N),FMIN



      DELTA =0.5D0
      DELTA1 =0.5D0

      ALFA=ALFA0
C      ALFA=DMAX1(ALFA0,1.D0)
C      ALFA=1.D0

      DO I=1,N
        Z(I)=X(I)+ALFA*D(I)
      END DO

      CALL FUNCT(Z,N,FZ)
      NUM_FUNCT=NUM_FUNCT+1

      IF(IPRINT.GE.1) THEN
	   WRITE(*,*) ' DNR =',DNR
         WRITE(1,*) ' DNR =',DNR
         WRITE(*,*) ' FZ =',FZ,'   ALFA =',ALFA,'   ALFA0 =',ALFA0
         WRITE(1,*) ' FZ =',FZ,'   ALFA =',ALFA,'   ALFA0 =',ALFA0
      ENDIF
      IF(IPRINT.GE.2) THEN
         DO I=1,N
            WRITE(*,*) ' Z(',I,')=',Z(I)
            WRITE(1,*) ' Z(',I,')=',Z(I)
         ENDDO
       ENDIF

C        FPAR= F-1.D-2*GAMMA*ALFA*ALFA*DNR*DNR
        FPAR= F-GAMMA*ALFA*ALFA*DNR*DNR
 11     CONTINUE
        IF(FZ.LE.FPAR) THEN
              ALFAEX=ALFA/DELTA1
C              ALFAEX=ALFA/.25D0
              DO I=1,N
                Z(I) = X(I)+ALFAEX*D(I)
              END DO      
              CALL FUNCT(Z,N,FZDELTA)
              NUM_FUNCT=NUM_FUNCT+1
C              FPAR= F-1.D-2*GAMMA*ALFAEX*ALFAEX*DNR*DNR
              FPAR= F-GAMMA*ALFAEX*ALFAEX*DNR*DNR
              IF(IPRINT.GE.1) THEN
                WRITE(*,*) ' FZex=',FZDELTA,'  ALFAEX=',ALFAEX  
                WRITE(1,*) ' FZex=',FZDELTA,'  ALFAEX=',ALFAEX
              ENDIF
              IF(IPRINT.GE.2) THEN
                DO I=1,N
                  WRITE(*,*) ' Z(',I,')=',Z(I)
                  WRITE(1,*) ' Z(',I,')=',Z(I)
                ENDDO
              ENDIF
               IF(FZDELTA.LE.FPAR) THEN
                   FZ=FZDELTA
                   ALFA=ALFAEX
                   GO TO 11
                ELSE
                   ALFA0=ALFA
                   RETURN
                END IF
C         ELSE
C 12        CONTINUE
CC           IF(ALFA.GE.ALFA0*2.D-0) THEN
C           IF(ALFA.GE.2.D-0) THEN
C              ALFA=DELTA*ALFA      
C              DO I=1,N
C               Z(I)=X(I)+ALFA*D(I)
CC              END DO     
C              CALL FUNCT(Z,N,FZ)
C              NUM_FUNCT=NUM_FUNCT+1
C              IF(IPRINT.GE.1) THEN
C               WRITE(*,*) ' FZ =',FZ,'   ALFA =',ALFA
C               WRITE(1,*) ' FZ =',FZ,'   ALFA =',ALFA
C              ENDIF
C              IF(IPRINT.GE.2) THEN
C               DO I=1,N
C                WRITE(*,*) ' Z(',I,')=',Z(I)
C                WRITE(1,*) ' Z(',I,')=',Z(I)
C               ENDDO
C              ENDIF              
C              FPAR= F-GAMMA*ALFA*ALFA*DNR*DNR
C              IF(FZ.LE.FPAR) THEN
C                ALFA0=ALFA
C                RETURN
C              ELSE
C                GO TO 12
C              END IF
C           ELSE
C              ALFA0=.5D0*ALFA
C              ALFA=0.D0
C              RETURN
C           END IF
        ELSE
         ALFA=0.D0
        END IF

              
       END


C*********************************************
C
C
C********************************************

      SUBROUTINE INIT_STEPS(N,DOLDALFA,X,F,NUM_FUNCT,
     *                      D,Z,FINIT)

      IMPLICIT NONE

      INTEGER N,I,J,IMIN,NUM_FUNCT,IPRIMA
      REAL*8 D(N),Z(N),Z1(N),DOLDALFA(N),FINIT(N,2)
      REAL*8 X(N),ALFA,FZ,ALFAMIN,DELTA1,DELTA2,FMIN,F,FZDELTA
      REAL*8 FPAR,GAMMA


      ALFAMIN=0.01D0
      DELTA1=0.5D0
	DELTA2=0.5D0
      GAMMA=1.D-6
      DO I=1,N
        IPRIMA=1

        ALFA=DOLDALFA(I)
C        ALFA=1.D-1*(1.D0+DABS(X(I)))
   1    CONTINUE

	  Z(I)=X(I)+ALFA*D(I)

        CALL FUNCT(Z,N,FZ)
        NUM_FUNCT=NUM_FUNCT+1
        FPAR= F
        IF (FZ.LE.FPAR) THEN

           IF(IPRIMA.EQ.1) THEN
   2          CONTINUE
  
              Z(I)=X(I)+(ALFA)/(DELTA2)*D(I)

              CALL FUNCT(Z,N,FZDELTA)
              NUM_FUNCT=NUM_FUNCT+1
              FPAR= F-GAMMA*ALFA*ALFA/(DELTA2*DELTA2)
              IF(FZDELTA.LE.FPAR) THEN
                  ALFA=ALFA/DELTA2
                  FZ=FZDELTA
                  GO TO 2
              END IF
           END IF
           DOLDALFA(I)=ALFA
           FINIT(I,1)=FZ
           FINIT(I,2)=1.D0


        ELSE

            Z(I)=X(I)-ALFA*D(I)

            CALL FUNCT(Z,N,FZ)
            NUM_FUNCT=NUM_FUNCT+1
            FPAR= F
            IF (FZ.LE.FPAR) THEN
               IF(IPRIMA.EQ.1) THEN
   3             CONTINUE

                 Z(I)=X(I)-(ALFA)/(DELTA2)*D(I)

                 CALL FUNCT(Z,N,FZDELTA)
                 NUM_FUNCT=NUM_FUNCT+1
                 FPAR= F-GAMMA*ALFA*ALFA/(DELTA2*DELTA2)
                 IF(FZDELTA.LE.FPAR) THEN
                    ALFA=ALFA/DELTA2
                    FZ=FZDELTA
                    GO TO 3
                 END IF
               END IF
               DOLDALFA(I)=ALFA
               FINIT(I,1)=FZ
               FINIT(I,2)=-1.D0

            ELSE
               IPRIMA=2
               IF (ALFA.GT.ALFAMIN) THEN
                  ALFA=DELTA1*ALFA
                  GO TO 1
               ELSE
                  DOLDALFA(I)=ALFAMIN
                  FINIT(I,1)=1.D+1
               END IF
            END IF
        END IF
C        WRITE(*,*) 'FINIT(I)',FINIT(I,1)

	  Z(I)=X(I)	   

      END DO

      FMIN=F
      IMIN=0
      DO I=1,N
         IF(FINIT(I,1).LT.FMIN) THEN
            IMIN=I
            FMIN=FINIT(I,1)
         END IF
      END DO
      F=FMIN

C      DO I=1,N
C        WRITE(*,*) 'DOLDALFA(I)',DOLDALFA(I)
C      END DO

      IF(IMIN.GT.0) THEN
        IF(FINIT(IMIN,2).GT.0.D0) THEN

           X(IMIN)=X(IMIN)+DOLDALFA(IMIN)*D(IMIN)

        ELSE

           X(IMIN)=X(IMIN)-DOLDALFA(IMIN)*D(IMIN)

        END IF
      END IF

      CALL FUNCT(X,N,FMIN)

C       WRITE(*,*) F,FMIN
C       PAUSE

	Z(IMIN)=X(IMIN)

      RETURN


      END
           
